﻿using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

/// <summary>
/// AES-CBC加密工具类（128/192/256位密钥）
/// </summary>
public static class AesCbcHelper
{
    /// <summary>
    /// AES加密（输出Base64字符串）
    /// </summary>
    /// <param name="plainText">明文</param>
    /// <param name="key">密钥（16/24/32字节）</param>
    /// <param name="iv">初始化向量（16字节）</param>
    public static string Encrypt(string plainText, byte[] key, byte[] iv)
    {
        // 参数校验
        ValidateKeyAndIV(key, iv);
        
        using (Aes aesAlg = Aes.Create())
        {
            // 配置加密参数
            aesAlg.Key = key;
            aesAlg.IV = iv;
            aesAlg.Mode = CipherMode.CBC;     // 设置为CBC模式[4,9](@ref)
            aesAlg.Padding = PaddingMode.PKCS7; // 使用PKCS#7填充[3,6](@ref)

            // 创建加密器
            ICryptoTransform encryptor = aesAlg.CreateEncryptor();
            
            // 执行加密
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    return Convert.ToBase64String(msEncrypt.ToArray());
                }
            }
        }
    }

    /// <summary>
    /// AES解密（输入Base64字符串）
    /// </summary>
    public static string Decrypt(string cipherText, byte[] key, byte[] iv)
    {
        ValidateKeyAndIV(key, iv);
        
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = key;
            aesAlg.IV = iv;
            aesAlg.Mode = CipherMode.CBC;
            aesAlg.Padding = PaddingMode.PKCS7;

            ICryptoTransform decryptor = aesAlg.CreateDecryptor();
            
            using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        return srDecrypt.ReadToEnd();
                    }
                }
            }
        }
    }

    /// <summary>
    /// 密钥与IV校验
    /// </summary>
    private static void ValidateKeyAndIV(byte[] key, byte[] iv)
    {
        if (!IsValidKeySize(key.Length))
            throw new ArgumentException("密钥长度应为16/24/32字节");
        
        if (iv.Length != 16)
            throw new ArgumentException("IV长度必须为16字节");
    }

    /// <summary>
    /// 验证密钥长度
    /// </summary>
    private static bool IsValidKeySize(int keySize)
    {
        return keySize == 16 || keySize == 24 || keySize == 32; // 支持128/192/256位[9](@ref)
    }
}